package com.gitee.wsl.flow.create.datasource.source


import com.gitee.wsl.ext.base.currentTimeMillis
import com.gitee.wsl.flow.create.datasource.BaseFlowDataSource
import com.gitee.wsl.flow.create.datasource.DataState
import com.gitee.wsl.flow.create.datasource.FlowDataSource
import com.gitee.wsl.flow.create.datasource.request.ExpiringRequest
import com.gitee.wsl.flow.create.datasource.request.Request
import com.gitee.wsl.flow.transform.map.map
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext

data class FlowDataSourceExpiringValue<T>(
    val value: T,
    val expiredMillis: Long
) {
    fun isExpired(): Boolean = expiredMillis < currentTimeMillis
}

abstract class BaseExpiringExecutableFlowDataSource<R : ExpiringRequest, T>(
    cacheDataSource: FlowDataSource<R, FlowDataSourceExpiringValue<T>>? = null,
    coroutineContext: CoroutineContext = EmptyCoroutineContext
) : BaseFlowDataSource<R, FlowDataSourceExpiringValue<T>>(cacheDataSource, coroutineContext) {

    override fun shouldRead(request: R, data: DataState<FlowDataSourceExpiringValue<T>>): Boolean {
        return when  {
             data.isOk -> request.requestType == Request.Type.REFRESH_CACHE || data.value.isExpired()
             data.isErr -> true
             else ->  true
        }
    }

    fun readValue(request: R) = read(request).map { it.value }
}